﻿/**
 * http://vkontakte.ru/app1850321_355679
 * @author Innokentiy Shuvalov
 */

package list;

import client.Channel;
import flash.display.Sprite;
import flash.text.TextFormat;
import gui.hug.HUGMultiLabel;
import gui.hug.HUGSprite;
import gui.hug.HUGScrollBar;
import gui.hug.HUGColors;
import gui.hug.Utils;
import gui.hug.HUGLabel;
import client.INews;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.MouseEvent;
import flash.events.Event;


class NewList extends HUGSprite {
	
    static private inline var SPACE_BETWEEN_ITEMS : UInt = 5;
	static private inline var HEIGHT : UInt = 450;
	
	// changeable variables
	private var w : UInt;
	private var W : UInt;			// ScrollBar width
	private var wid : Float ;
	private var content : Array < ItemPanel >;
	private var firstShownItem : UInt;
	private var scrollBar : ScrollBar;
	//private var previousSBPosition : Float;
	private var label : HUGLabel;
	private var H: UInt;
	
	
	public function new(left : UInt = 0, top : UInt = 0,type:Int, listWidth : UInt = 600) {
		super();
		setLocation(left, top);
		w = listWidth;
		W = ScrollBar.getWidth();
		
		
		init();
		draw();

	}
	
	private function init() {
		
		firstShownItem = 0;
		content = new Array();
		
		// Scroll bar
		scrollBar = new ScrollBar( w - W , 0, 400);//Std.Int(getLength) );
		
		//previousSBPosition = 0;
		scrollBar.addEventListener( Event.SCROLL, onScrollEvent );
		addChild(scrollBar);
		
		// EVENTS---------------------------------------------------------
		addEventListener( MouseEvent.MOUSE_WHEEL, onWheel );
		addEventListener( ScrollEvent.SCROLL, onScrollEvent );
	}
	
	
	/////// USER METHODS /////////////////////////////////////////////////////////////////////////////
	
	public function draw() {
		// background and border
		//Utils.rect( this, 0, 0, w - 1, HEIGHT - 1, HUGColors.WHITE, HUGColors.VK_BORDER_OUTER, 1 );
		
		popScreen();
		drawScrollBar();
		drawContent();
	}
	
	//mouse on panel or out panel
	public function scrollTo( ?index : UInt) {
		if (index == null) index = getQuantity() ;
		while (index < firstShownItem)
			moveScreen( -1);
		while (index >= getLastOnScreen())
			moveScreen(1);
	}
	
	// ADD-METHODS    ----------------------------------------------------
	public function addItem( item : INews,type:Int ) {
		content.push( new ItemPanel( w - W  - 2 * SPACE_BETWEEN_ITEMS, item, getQuantity(), type ) ) ;
		draw();
	}
	
	public function addItems( news : Array < INews >,type:Int ) {
		for (item in news) {
			content.push( new ItemPanel( w - W - 2 * SPACE_BETWEEN_ITEMS, item, getQuantity(),type  ) ) ;
		}
		draw();
	}
	
	// GET-METHODS    ----------------------------------------------------
	public function getQuantity() : UInt{
		return content.length; }
		
    public function getWidth() : UInt {
		return w; }
    
    public function getItem(index : UInt) : INews {
		return content[index].getContent() ;
	}
	
	public function getLength( begin : UInt = 0,  ?end : UInt ) : Float {
		if ( end == null ) end = getQuantity();
		var currentHeight : Float = 0;
		var index : UInt = begin;
		while ( begin < end ) {
			currentHeight += content[begin].getHeight() + SPACE_BETWEEN_ITEMS;
			begin ++ ;
		}
		
		return currentHeight;
	}
	
	// CHANGE CONTENT  ----------------------------------------------------
	
	/**
	 * @param	mode	in case it is 'true' the item becomes hidden
	 * and only a one more execution of this method with 'false' parameter
	 * can make it visible again!
	 * @param	index	the element to hide
	 */
	public function hide(index : UInt, mode : Bool = true) {
		content[index].hide(mode);
	}
	
	public function deleteItem(index : UInt) {
		if ( index < getQuantity() - 1 )
			for ( i in index ... ( getQuantity() - 2 ) ) {
				content[i] = content[i + 1];
				content[i].reduceId() ;
			}
		content.pop();
	}
	
	public function clearContent() {
		content = new Array<ItemPanel>();
	}
	
	/// PRIVATE METHODS ////////////////////////////////////////////////////////////////////////////
	
	private function getLastOnScreen() : UInt {
		var result = firstShownItem;
		var currentHeight : Float = 0;
		
		for ( i in firstShownItem ... getQuantity() ) {
			currentHeight += content[i].getHeight() == 0 ?  0 : (content[i].getHeight() + SPACE_BETWEEN_ITEMS);
			if ( currentHeight > HEIGHT ) return result;
			result ++ ;
		}
		
		return result;
	}
	
	private function drawContent() {
		if ( getQuantity() > 0 ) {
			var currentHeight : Float = 0;
			var end = getLastOnScreen() + 1;
			for ( index in firstShownItem ... end ) {
				if(content[index] != null ) {
					// drawing itemPanel
					content[index].setLocation(SPACE_BETWEEN_ITEMS, currentHeight );
					
					addChild(content[index]);
					var aditional = content[index].getHeight();
					currentHeight += aditional;
					
					
					// filling space between the items
					var space : HUGSprite = new HUGSprite(SPACE_BETWEEN_ITEMS, currentHeight );
					Utils.fillRect( space, -1, 0, w - W - 2 * SPACE_BETWEEN_ITEMS  + 2, SPACE_BETWEEN_ITEMS, HUGColors.VK_BACKGROUND );
					addChild(space);
					if ( aditional != 0 ) currentHeight += SPACE_BETWEEN_ITEMS;
				    
					wid = this.width;
				}
			}
			
			// filling the space that is left after all the items are drawn
			var space : HUGSprite = new HUGSprite(SPACE_BETWEEN_ITEMS , currentHeight -5);
			
			Utils.fillRect( space, -1, 0, w - W - 2 * SPACE_BETWEEN_ITEMS + 2, HEIGHT - currentHeight , HUGColors.VK_BACKGROUND );
			addChild(space);
		}
	}
	
	/**
	 * reduces the first shown item,
	 * if there is a lot of space left
	 * below the list.
	 */
	private function popScreen() {
		if ( getLastOnScreen() == getQuantity()) {	
			while ( getLastOnScreen() == getQuantity()  )
				firstShownItem -- ;
			firstShownItem ++ ;
		}
	}

	/**
	 * @param	delta	the amount of items, you want to scroll.
	 * default delta is zero. you can use it just to update the screen
	 */
	private function moveScreen(delta : Int = 0) {  
		if ( getLength() > HEIGHT ) {
			firstShownItem = firstShownItem + delta <= 0 ? 0 : firstShownItem + delta;
			draw();
		}
	}
	
	/**
	 * this method is needed to find the maximum scroll position
	 * @return index of the maximum item which can be set as firstShownItem
	 */
	private function getLastFirstShown() : UInt {
		var result = firstShownItem;
		while ( getLength ( result ) > HEIGHT ) result ++ ;
		return result;
	}
    
	private function drawScrollBar() {
		scrollBar.setSliderPosition( firstShownItem );
		scrollBar.visible =  getLength() > HEIGHT;
	}
	
	
	/// EVEMT HANDLERS ///////////////////////////////////////////////////////////////////////////
	
	private function onWheel ( e : MouseEvent) {
		moveScreen ( e.delta < 0 ? 1 : -1 );
	}
	
	/*private function onScroll ( e : Event ) {
		moveScreen ( Std.int( scrollBar.getScrollPosition() - previousSBPosition ) );
		previousSBPosition = scrollBar.getScrollPosition();
	}*/
	
	private function onScrollEvent ( e : ScrollEvent ) {
		switch ( e.getScrollMode() ) {
			case ScrollEvent.UP : moveScreen( -1);
			case ScrollEvent.DOWN : moveScreen(1);
			case ScrollEvent.TWO_UP : moveScreen( -2);
			case ScrollEvent.TWO_DOWN : moveScreen(2);
			case ScrollEvent.PAGE_DOWN : moveScreen( getLastOnScreen() - firstShownItem + 1 );
			case ScrollEvent.PAGE_UP : moveScreen( -getLastOnScreen() + firstShownItem - 1);
			case ScrollEvent.END : moveScreen( getQuantity() );
			case ScrollEvent.HOME : moveScreen( -getQuantity() );
		}
	}
}